package com.horoscope.astrology.zodiac.signs.free.network

import com.horoscope.astrology.zodiac.signs.free.MmoApplication
import com.horoscope.astrology.zodiac.signs.free.MmoConstant
import com.horoscope.astrology.zodiac.signs.free.utils.Logger
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Converter
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.net.URL
import java.security.KeyStore
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.*

class HttpEngine {

    companion object {
        private var B_URL = MmoApplication.getInstance().getHostIP()
        private var BASE_URL = MmoApplication.getInstance().getHostIP()
        private const val cityBaseUrl = "https://secure.geonames.org/"
        private val TAG = HttpEngine::class.java.simpleName
        // 设置基础请求路径
        fun setCityUrl() {
            BASE_URL = cityBaseUrl
        }

        // 设置基础请求路径
        fun setBASEUrl() {
            BASE_URL = B_URL
        }
    }

    private var okHttpClient: OkHttpClient? = null

    private var retrofit: Retrofit? = null

    private val TRUST_MANAGER = object : X509TrustManager {
        @Throws(CertificateException::class)
        override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
        }

        @Throws(CertificateException::class)
        override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
        }

        override fun getAcceptedIssuers(): Array<X509Certificate?> {
            return arrayOfNulls(0)
        }
    }

    /**
     * 主要通过OkHttp创建Retrofit客户端
     * addInterceptor -> 设置Log日志
     * connectTimeout -> 设置请求超时
     * setDefaultSslSocketFactory(clientBuilder) -> 设置https访问(验证证书，请把服务器给的证书文件放在R.raw文件夹下)
     * */
    private fun getOkHttpClient(): OkHttpClient {
        if (null == okHttpClient) {
            val clientBuilder =
                OkHttpClient.Builder()
                    .addInterceptor(getInterceptor())
                    .connectTimeout(60, TimeUnit.SECONDS)
            /*val uri = URL(BASE_URL).toURI()
             if ("https" == uri.scheme) {
                 setSslSocketFactory(clientBuilder)
             } else {
             }*/
            setDefaultSslSocketFactory(clientBuilder)
            okHttpClient = clientBuilder.build()
        }
        return okHttpClient!!
    }

//    /**
//     * 设置HTTPS认证
//     */
//    private fun setSslSocketFactory(clientBuilder: OkHttpClient.Builder) {
//        val sslContext = getSSLContext()
//        if (sslContext != null) {
//            clientBuilder.sslSocketFactory(sslContext.socketFactory, TRUST_MANAGER)
//            clientBuilder.hostnameVerifier(HostnameVerifier { hostname, session ->
//                if (MmoConstant.HOST_IP == hostname) {//校验hostname是否正确，如果正确则建立连接
//                    return@HostnameVerifier true
//                }
//                false
//            })
//        }
//    }

    /**
     * Retrofit②
     * 创建Retrofit客户端
     * addConverterFactory -> 开启Gson装换
     * addCallAdapterFactory -> 配置回调库，启用Rxjava
     * baseUrl -> 设置基础请求路径
     * */
    private fun getRetrofit(): Retrofit {
        if (null == retrofit) {
            retrofit = Retrofit.Builder().baseUrl(BASE_URL!!)
                .addConverterFactory(getFactory())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(getOkHttpClient()).build()
        }
        return retrofit!!
    }

    // 开启Gson转换
    private fun getFactory(): Converter.Factory {

        return GsonConverterFactory.create()
    }

    /**
     * 设置HTTPS认证：默认信任所有证书
     */
    private fun setDefaultSslSocketFactory(clientBuilder: OkHttpClient.Builder) {
//        okHttpClientBuilder.hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        clientBuilder.hostnameVerifier { _, _ ->
            true
        }
        try {
            val sc = SSLContext.getInstance("TLS")
            sc.init(null, arrayOf<TrustManager>(TRUST_MANAGER), SecureRandom())
            clientBuilder.sslSocketFactory(sc.socketFactory, TRUST_MANAGER)
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    fun getApiCenter(): ApiCenter {
        return getRetrofit().create(ApiCenter::class.java)
    }

    // 开启Log日志
    private fun getInterceptor(): HttpLoggingInterceptor {
        val loggingInterceptor = HttpLoggingInterceptor(HttpLoggingInterceptor.Logger {
            Logger.debug("retrofit", it)
        })
        loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        return loggingInterceptor
    }

    private fun getSSLContext(): SSLContext? {
        var sslContext: SSLContext? = null
        try {
            sslContext = SSLContext.getInstance("TLS")
            val inputStream = MmoApplication.getInstance().getCertificateInputStream()
            val cerFactory = CertificateFactory.getInstance("X.509")
            val cer = cerFactory.generateCertificate(inputStream)
            val keyStore = KeyStore.getInstance("PKCS12")
            keyStore.load(null, null)
            keyStore.setCertificateEntry("trust", cer)
            val keyManagerFactory =
                KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
            keyManagerFactory.init(keyStore, null)
            val trustManagerFactory =
                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
            trustManagerFactory.init(keyStore)
            sslContext.init(
                keyManagerFactory.keyManagers,
                trustManagerFactory.trustManagers,
                SecureRandom()
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return sslContext
    }

}

/* 设置缓存
Interceptor cacheIntercepter=new Interceptor() {
     @Override
     public Response intercept(Chain chain) throws IOException {
         //对request的设置用来指定有网/无网下所走的方式
         //对response的设置用来指定有网/无网下的缓存时长

         Request request = chain.request();
         if (!NetworkUtil.isNetWorkAvailable(mContext)) {
             //无网络下强制使用缓存，无论缓存是否过期,此时该请求实际上不会被发送出去。
             //有网络时则根据缓存时长来决定是否发出请求
             request = request.newBuilder()
             .cacheControl(CacheControl.FORCE_CACHE).build();
         }

         Response response = chain.proceed(request);
         if (NetworkUtil.isNetWorkAvailable(mContext)) {
             //有网络情况下，超过1分钟，则重新请求，否则直接使用缓存数据
             int maxAge = 60; //缓存一分钟
             String cacheControl = "public,max-age=" + maxAge;
             //当然如果你想在有网络的情况下都直接走网络，那么只需要
             //将其超时时间maxAge设为0即可
              return response.newBuilder()
              .header("Cache-Control",cacheControl)
              .removeHeader("Pragma").build();
         } else {
             //无网络时直接取缓存数据，该缓存数据保存1周
             int maxStale = 60 * 60 * 24 * 7 * 1;  //1周
             return response.newBuilder()
             .header("Cache-Control", "public,only-if-cached,max-stale=" + maxStale)
             .removeHeader("Pragma").build();
         }

     }
 };

File cacheFile = new File(mContext.getExternalCacheDir(), "HttpCache");//缓存地址
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50); //大小50Mb

//设置缓存方式、时长、地址
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.addNetworkInterceptor(cacheIntercepter);
okHttpClientBuilder.addInterceptor(cacheIntercepter);
okHttpClientBuilder.cache(cache);
*/